<?php

/*
Copyright 2009-2011 Sam Weiss
All Rights Reserved.

This file is part of Spark/Plug.

Spark/Plug is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

if (!defined('spark/plug'))
{
	header('HTTP/1.1 403 Forbidden');
	exit('<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN"><html><head><title>403 Forbidden</title></head><body><h1>Forbidden</h1><p>You don\'t have permission to access the requested resource on this server.</p></body></html>');
}

// -----------------------------------------------------------------------------

class _SparkCacher_memcache extends SparkCacher
{
	private $_default_timeout;
	private $_name_space;
	private $_generation;
	private $_prefix;
	private $_memcache;

	// --------------------------------------------------------------------------

	public function __construct($params)
	{
		parent::__construct($params);
		
		$this->_setupConnection($params);

		$this->_default_timeout = !empty($params['lifetime']) ? $params['lifetime'] : 0;
		$this->_name_space = '';
		$this->_generation = false;
		$this->_prefix = '';
		
		$this->setNameSpace(@$params['namespace']);
	}

	// --------------------------------------------------------------------------

	// Public Methods

	// --------------------------------------------------------------------

	public function setDefaultTimeout($timeout)
	{
		$this->_default_timeout = !empty($timeout) ? $timeout : 0;
	}

	// --------------------------------------------------------------------------

	public function setNameSpace($namespace)
	{
		if (empty($namespace))
		{
			$namespace = '';
		}
		
		if ($this->_name_space != $namespace)
		{
			$this->_name_space = $namespace;
	
			if (empty($this->_name_space))
			{
				$this->_prefix = '';
			}
			else
			{
				if (($this->_generation = $this->_memcache->get($this->_name_space.':generation')) === false)
				{
					$this->_memcache->set($this->_name_space.':generation', $this->_generation = '0', false, 0);
				}
				$this->_prefix = $this->_generation . ':' . $this->_name_space . ':';
			}
		}
	}

	// --------------------------------------------------------------------------

	public function get($key)
	{
		return $this->_memcache->get($this->_prefix.$key);
	}

	// --------------------------------------------------------------------------

	public function set($key, $item, $timeout = NULL)
	{
		return $this->_memcache->set($this->_prefix.$key, $item, false, $timeout !== NULL ? $timeout : $this->_default_timeout);
	}

	// --------------------------------------------------------------------------

	public function replace($key, $item, $timeout = NULL)
	{
		return $this->_memcache->replace($this->_prefix.$key, $item, false, $timeout !== NULL ? $timeout : $this->_default_timeout);
	}

	// --------------------------------------------------------------------------

	public function remove($key)
	{
		return $this->_memcache->delete($this->_prefix.$key);
	}

	// --------------------------------------------------------------------------

	public function clear()
	{
		if (empty($this->_name_space))
		{
			return $this->_memcache->flush();
		}
		else
		{
			$this->_generation = $this->_memcache->increment($this->_name_space.':generation');
			$this->_prefix = $this->_generation . ':' . $this->_name_space . ':';
			return ($this->_generation !== false);
		}
	}

	// --------------------------------------------------------------------------

	// Private Methods

	// --------------------------------------------------------------------------

	private function _setupConnection($params)
	{		
		if (isset($params['options']['hosts']))
		{
			$hosts =& $params['options']['hosts'];
		}
		else
		{
			$hosts[] = array();
		}
		
		$this->_memcache = new Memcache;

		foreach($hosts as $hostInfo)
		{
			$host = isset($hostInfo['host']) ? $hostInfo['host'] : 'localhost';
			$port = isset($hostInfo['port']) ? $hostInfo['port'] : 11211;
			$persistent = isset($hostInfo['persistent']) ? $hostInfo['persistent'] : true;
			$weight = isset($hostInfo['weight']) ? $hostInfo['weight'] : 1;
			$timeout = isset($hostInfo['timeout']) ? $hostInfo['timeout'] : 1;
			$retry = isset($hostInfo['retry']) ? $hostInfo['retry'] : 15;

			$this->_memcache->addServer($host, $port, $persistent, $weight, $timeout, $retry);
		}
	}

	// --------------------------------------------------------------------------
}
